/**
 * 
 */
package org.zgstudio.ddlchecker;

import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author zhguo
 * 
 */
public class SimpleLinkCheck implements LinkCheck {

    private int                numThreads         = 5;

    private static int         coreThreadPoolSize = 5;
    private static int         maxPoolSize        = 10;
    private static int         threadIdleTime     = 60; // seconds

    private ThreadPoolExecutor executor;
    private ResultChecker      rc;

    public SimpleLinkCheck(ResultChecker rc) {
        this.rc = rc;
        ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
                1000);
        executor = new ThreadPoolExecutor(coreThreadPoolSize, maxPoolSize,
                threadIdleTime, TimeUnit.SECONDS, queue);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.zgstudio.ddlchecker.LinkCheck#checkLinks(org.zgstudio.ddlchecker.
     * Link[])
     */
    @Override
    public Collection<LinkCheckResult> checkLinks(Link[] links)
            throws TooManyURLsInTaskException {
        
        LinkCheckTaskPool taskPool = new SimpleLinkCheckTaskPool();
        taskPool.build(links);

        if (rc != null)
            rc.startChecking();

        while (true) {
            final LinkCheckTask task = taskPool.getNextTask();
            if (task == null)
                break;
            executor.submit(new LinkCheckUtil(task, this));
        }
        executor.shutdown();

        while (!executor.isTerminated()) {
            synchronized (this) {
                try {
                    wait(1000 * 1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        rc.setCompleted(true);
        return null;
    }

    public void notifyComplete() {
        synchronized (this) {
            this.notify();
        }
    }
}
